package visualcbir.visualstructures.spiral;

import visualcbir.*;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Observable;
import visualcbir.node.ModelNode;
import visualcbir.node.ViewNode;
import visualcbir.visualstructures.ring.VSRings;

/**
 *
 * @author sheila
 */
public class VSSpiral extends ViewComposed{

    public VSSpiral(ModelComposed oModel, int piNumSubViews){
        super(oModel, piNumSubViews);
    }

    @Override
    public IBackStructureView makeBackStructureView(){
        return new VSSpiralBackStructureView();
    }

    @Override
    public void update(Observable o, Object arg) {        
        setSpiralFermat(o,arg);
        System.out.println("SPIRAL UPDATE");
    }

    /**
     *  r: radio
     *  Theta: angle in radians
     *  a: spiral curvature. Usual values: [81-95-115]
     *  r^2 = (a^2)*Theta 
     */
    public void setSpiralFermat(Observable o, Object arg){
        ArrayList <Point> aoPoints = new ArrayList<Point>();
        double r=0;
        double scaleFactorSubViews = 0.90 * this.getScaleFactor(); //scala de todo dos subclusters e da img central
        double a=90;//shi/ * this.getScaleFactor();
        double x, y, numRotations=10;
        double thetaRad;
        int iNodeNumber=0;
        double angleNode=0;
        
        for(double theta=0;theta<360*numRotations && (iNodeNumber < ((ModelComposed)oModel).getNumModels()) && iNodeNumber<this.iNumSubviews;theta++){
            thetaRad = theta*(Math.PI/180);
            r = Math.sqrt((Math.pow(a,2))*thetaRad)  * this.getScaleFactor();
            x = ( r * Math.cos(thetaRad) + this.getCenterPoint().x);
            y = ( r * Math.sin(thetaRad) + this.getCenterPoint().y);
             
            aoPoints.add(new Point((int)Math.round(x),(int)Math.round(y)));
            if(theta==angleNode ){
                super.getView(iNodeNumber).setCenterPoint((int)Math.round(x), (int)Math.round(y));
                super.getView(iNodeNumber).setScaleFactor(scaleFactorSubViews-= 0.009);//0.011
                
                angleNode += (int) Math.round( this.getAngleIncrement(iNodeNumber) );
                iNodeNumber++;
            }
        }
        
        super.oIBackStructureView.setObject(aoPoints);
        super.setViewDimension( (int) r*2 +100, (int)r*2 +100 );//+ (int) Math.round(((ViewNode)getMaxSizeSubView()).getNodeHeight())

        super.update(o,arg);// updating all subviews.
    }

    public double getAngleIncrement(int x){        
        double y = 1/Math.log10(x+2)*36;//double y = Math.pow(1/2,x)*100  ;
        return y;
    }
    

    @Override
    public void addView(Model oModelAdded) {
        if(oModelAdded instanceof ModelNode)
            super.addView(new ViewNode((ModelNode)oModelAdded));        
        else if(oModelAdded instanceof ModelComposed){
            //super.addView(new VSSpiral((ModelComposed)oModelAdded,13));
            super.addView(new VSRings((ModelComposed)oModelAdded,13));
         }
    }
}
